 ///
 /// @file    String.cc
 /// @author  lemon(haohb13@gmail.com)
 /// @date    2018-10-30 09:55:05
 ///
 
#include <string.h>
#include <iostream>
using namespace std;

class String
{
public:
	String()
	: _pstr(new char[1]())// new []() ,加小括号时是会初始化为0
	{	
		cout << "String()" << endl;
	}

	String(const char * pstr)
	: _pstr(new char[strlen(pstr) + 1]())
	{
		strcpy(_pstr, pstr);
		cout << "String(const char * pstr)" << endl;
	}

    //拷贝构造函数
	String(const String & rhs)
	: _pstr(new char[strlen(rhs._pstr) + 1]())
	{   //先开辟空间，再复制内容，这就是深拷贝
		strcpy(_pstr, rhs._pstr);
		cout << "String(const String & rhs)" << endl;
	}

    //赋值运算符函数
	String & operator=(const String & rhs)
	{
		cout << "String & operator=(const String &)" << endl;
		if(this != &rhs) {   //1. 自复制
			delete [] _pstr; //2. 回收左操作数空间

			_pstr = new char[strlen(rhs._pstr) + 1]();//3. 深拷贝
			strcpy(_pstr, rhs._pstr);
		}
		return *this;
	}

	~String() 
	{
		if(_pstr) {
			delete [] _pstr;
		}
		cout << "~String()" << endl;
	}

    const char * c_str() const {    return _pstr;   }

    friend ostream & operator<<(ostream &os, const String& rhs);
private:
	char * _pstr;
};

ostream & operator<<(ostream &os, const String& rhs)
{
    if(rhs._pstr) {
        os << rhs._pstr;
    }
    return os;
}
 
int main(void)
{
	String s1;
    cout << "s1:" << s1 << endl;
	String s2("hello");
	cout << "s2:" << s2 << endl << endl;

	String s3 = s2;//复制构造,深拷贝
    cout << "执行完String s3 = s2 语句之后:" << endl;
	cout << "s3:" << s3 << endl;
    printf("s2's c_str: %p\n", s2.c_str());
    printf("s3's c_str: %p\n\n", s3.c_str());

	String s4 = "world";
	cout << "s4 = " << s4 << endl << endl;

    s4 = s2;//赋值操作
    cout << "经过赋值操作s4 = s2 之后:" << endl;
	cout << "s4 = " << s4 << endl;
    printf("s4's c_str: %p\n\n", s4.c_str());

    printf("&s1: %p\n", &s1);
    printf("&s2: %p\n", &s2);
    printf("&s3: %p\n", &s3);
    printf("&s4: %p\n", &s4);
	return 0;
}
